package com.ycz.sas.jgen.ui;

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.filechooser.FileFilter;
import javax.swing.tree.TreePath;

import com.ycz.sas.jgen.domain.CacheInfo;
import com.ycz.sas.jgen.domain.CheckBoxFileTreeNode;
import com.ycz.sas.jgen.handler.ChooseDirListener;
import com.ycz.sas.jgen.handler.ConfigDataHandler;
import com.ycz.sas.jgen.handler.FileOprate;
import com.ycz.sas.jgen.main.ContextUtil;
import com.ycz.sas.jgen.util.Resource;

public class JarToolUI extends JFrame{

	private static final long serialVersionUID = 7462519373177235173L;

	CheckBoxFileTree tree;

	JLabel contTreePath;

	JScrollPane scrollPane;

	JTextArea taAnaResult;
	JTextArea taIgnoreFolders;

	JTextField txtComparePath;
	JTextField txtCustomPath;
	JTextField txtTargetPath;
	JTextField txtConfigPath;
	JTextField txtJarPath;

	private ConfigDataHandler handler;
	private static String JGEN_HOME;
	private static String CONFIG_PATH;
	private static String DESTJAT_PATH;
	private static String LOG_PATH;

	boolean flag = true;

	public JarToolUI(){
		super("分包部署工具");
		
		Resource res = new Resource();
		JGEN_HOME = ContextUtil.getHome();
		CONFIG_PATH = JGEN_HOME + ContextUtil.getConfigPath();
		DESTJAT_PATH = JGEN_HOME + ContextUtil.getJarPath();
		LOG_PATH = JGEN_HOME + ContextUtil.getLogPath();
		
		handler = new ConfigDataHandler();

		initMenuBar();
		initLayout();
		initStatusBar();

		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setVisible(true);
		setExtendedState(MAXIMIZED_BOTH);

	}

	private void initMenuBar(){
		JMenuBar mb=new JMenuBar();
		add(mb,"North");
		JMenu file=new JMenu("File");
		mb.add(file);
		JMenuItem open=new JMenuItem("Open");
		open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,
				InputEvent.CTRL_MASK));
		file.add(open);
		JMenuItem save=new JMenuItem("Save");
		save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
				InputEvent.CTRL_MASK));
		file.add(save);
		JMenuItem saveTo=new JMenuItem("SaveTo");
		saveTo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_D,
				InputEvent.CTRL_MASK));
		file.add(saveTo);
		JMenuItem quit=new JMenuItem("Quit");
		quit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
				InputEvent.CTRL_MASK));
		file.add(quit);

		JMenu ctrl=new JMenu("Control");
		mb.add(ctrl);
		JMenuItem expand=new JMenuItem("Expand");
		ctrl.add(expand);
		JMenuItem collapse=new JMenuItem("Collapse");
		ctrl.add(collapse);
		JMenuItem switchTree=new JMenuItem("TreeSwitch");
		switchTree.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T,
				InputEvent.CTRL_MASK));
		ctrl.add(switchTree);
		JMenuItem batchJar=new JMenuItem("BatchJar");
		batchJar.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B,
				InputEvent.CTRL_MASK));
		ctrl.add(batchJar);
		
		JMenu tools = new JMenu("Tools");
		mb.add(tools);
		JMenuItem licence=new JMenuItem("Licence");
		tools.add(licence);
		licence.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L,
				InputEvent.CTRL_MASK));
		JMenuItem track=new JMenuItem("Track");
		tools.add(track);
		track.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_K,
				InputEvent.CTRL_MASK));

		JMenu network=new JMenu("NetWork");
		mb.add(network);
		JMenuItem ftp=new JMenuItem("FTP");
		network.add(ftp);
		ftp.setAccelerator(KeyStroke.getKeyStroke("F8"));

		open.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				actionOpen();
			}
		});
		save.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				actionSave();
			}
		});
		saveTo.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				actionSaveTo();
			}
		});

		quit.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				actionQuit();
			}
		});
		expand.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				actionExpand();
			}
		});
		collapse.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				actionCollapse();
			}
		});
		switchTree.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				actionSwitchTree();
			}
		});
		batchJar.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				actionBatchJar();
			}
		});
		licence.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				actionLicence();
			}
		});
		track.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				actionTrack();
			}
		});
		ftp.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				actionFtp();
			}
		});
	}

	private void initLayout(){
		Container contentPane = getContentPane();
		scrollPane = new JScrollPane();
		scrollPane.setViewportView(tree);

		JPanel panel = new JPanel(new GridLayout(1, 2));
		contentPane.add(panel, "Center");

		panel.add(scrollPane);

		JPanel ctrlPanel = new JPanel();
		ctrlPanel.setLayout(new GridLayout(2, 1));


		JPanel anaPanel = new JPanel();
		anaPanel.setLayout(new FlowLayout(0));
		JButton analyse = new JButton();
		analyse.setText("对比分析");

		analyse.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				actionAnalyse();
			}
		});

		taAnaResult = new JTextArea(20, 56);
		taAnaResult.setLineWrap(true);
		taAnaResult.setEditable(false);

		JScrollPane scrollrs = new JScrollPane();
		scrollrs.setViewportView(taAnaResult);

		anaPanel.add(analyse);
		anaPanel.add(scrollrs);
		ctrlPanel.add(anaPanel);

		JPanel jarPanel = new JPanel();
		jarPanel.setLayout(new FlowLayout(2));
//		jarPanel.setLayout(new GridLayout(6, 1));

		JLabel contBasePath = new JLabel("基准路径");
		txtComparePath = new JTextField(50);
		ChooseDirListener baselis = new ChooseDirListener(txtComparePath, JGEN_HOME);
		txtComparePath.addMouseListener(baselis);

		JLabel contCustomPath = new JLabel("本地路径");
		txtCustomPath = new JTextField(50);
		ChooseDirListener customlis = new ChooseDirListener(txtCustomPath, JGEN_HOME);
		txtCustomPath.addMouseListener(customlis);

		JLabel contUpdatePath = new JLabel("升级路径");
		txtTargetPath = new JTextField(50);
		ChooseDirListener updatelis = new ChooseDirListener(txtTargetPath, JGEN_HOME);
		txtTargetPath.addMouseListener(updatelis);

		JLabel contConfigPath = new JLabel("配置文件");
		txtConfigPath = new JTextField(50);
		txtConfigPath.setEditable(false);

		JLabel contJarPath = new JLabel("JAR包路径");
		txtJarPath = new JTextField(50);
		ChooseDirListener jarpathlis = new ChooseDirListener(txtJarPath, JGEN_HOME);
		txtJarPath.addMouseListener(jarpathlis);

		JLabel contIgnoreFolders = new JLabel("例外路径");
		taIgnoreFolders = new JTextArea(2, 50);
		taIgnoreFolders.setLineWrap(true);
		ChooseDirListener jarignore = new ChooseDirListener(taIgnoreFolders, JGEN_HOME);
		taIgnoreFolders.addMouseListener(jarignore);
		JScrollPane scrollignore = new JScrollPane();
		scrollignore.setViewportView(taIgnoreFolders);

		JButton generate = new JButton();
		generate.setText("生成JAR文件");
		generate.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				actionGenerate();
			}
		});



		jarPanel.add(contConfigPath);
		jarPanel.add(txtConfigPath);
		jarPanel.add(contBasePath);
		jarPanel.add(txtComparePath);
		jarPanel.add(contCustomPath);
		jarPanel.add(txtCustomPath);
		jarPanel.add(contUpdatePath);
		jarPanel.add(txtTargetPath);
		jarPanel.add(contJarPath);
		jarPanel.add(txtJarPath);
		jarPanel.add(contIgnoreFolders);
		jarPanel.add(scrollignore);

		jarPanel.add(generate);


		ctrlPanel.add(jarPanel);

		panel.add(ctrlPanel);

		pack();
	}

	private void initStatusBar(){
		JPanel statuspanel = new JPanel();
		statuspanel.setLayout(new FlowLayout(0));
		add(statuspanel, "South");

		JLabel lbTreePath = new JLabel();
		lbTreePath.setText("树路径\t");
		contTreePath = new JLabel();
		contTreePath.setText(getSourcePath());


		statuspanel.add(lbTreePath);
		statuspanel.add(contTreePath);
	}

	protected void actionGenerate(){
		String jarPath = "";
		try {
			jarPath = handler.generateJar();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			reportLog(jarPath);
			JOptionPane.showMessageDialog(this, "Jar File Generate Success:\n"+jarPath);
		}
	}

	private void reportLog(String jarFile){
		FileOprate fileop = new FileOprate();

		SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
		long logfileName = Long.valueOf(sdf.format(new Date()));

		fileop.newFolder(LOG_PATH);
		fileop.newFolder(LOG_PATH + logfileName);

		File jar = new File(jarFile);

		String target = LOG_PATH + logfileName + "/" + jar.getName();
		String newName = target;
		int i = 1;
		while(new File(newName).exists()){
			newName = target + "_" + i;
			i++;
		}
		fileop.copyFile(jarFile, newName);
	}

	protected void actionAnalyse(){
		try {
			checkFileTree();
			String result = handler.analyse();

			CheckBoxFileTreeNode rootNode = tree.getRootNode();
			loadData2Tree(new TreePath(rootNode), result);
			tree.repaint();
			taAnaResult.setText(result);
		} catch (Exception e) {
//			e.printStackTrace();
		}
	}

	protected void actionOpen(){
		try{
			JFileChooser chooser = new JFileChooser();
			chooser.setFileFilter(new FileFilter() {

				@Override
				public String getDescription() {
					String strFileDesc = "Config File(*.cfg)";
					return strFileDesc;
				}

				@Override
				public boolean accept(File file) {
					String strFileExt = ".cfg";
					if(file.isDirectory() || file.getName().endsWith(strFileExt))
						return true;
					else
						return false;
				}
			});
			chooser.setAcceptAllFileFilterUsed(false);
			chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
			chooser.setDialogTitle("选择配置文件");
			chooser.setCurrentDirectory(new File(CONFIG_PATH));
			int ok = chooser.showOpenDialog(this);
			if (ok == JFileChooser.OPEN_DIALOG) {
				File cfgFile = chooser.getSelectedFile();
				if (cfgFile.exists()) {
					String fileName = cfgFile.getAbsolutePath();
					String oldCfgFile = handler.getCache().getConfigPath();
					handler.releaseCfgFile(oldCfgFile);
					txtConfigPath.setText(fileName);
					handler.reset();
					handler.lockCfgFile(fileName);
					handler.getCache().setConfigPath(fileName);
					handler.loadConfigData(fileName);
					loadConfig2UI();
				}
			}
		}catch (Exception e) {
		}
	}


	private void loadConfig2UI(){
		CacheInfo cache = handler.getCache();
		taAnaResult.setText(null);
		txtComparePath.setText(cache.getComparePath());
		txtCustomPath.setText(cache.getCustomPath());
		txtTargetPath.setText(cache.getTargetPath());
		txtJarPath.setText(cache.getJarPath());
		taIgnoreFolders.setText(cache.getIgnoreFolders());
		loadTree();

		CheckBoxFileTreeNode rootNode = tree.getRootNode();
		loadData2Tree(new TreePath(rootNode));
		tree.repaint();
	}

	private void loadData2Tree(TreePath parent){
		CheckBoxFileTreeNode node = (CheckBoxFileTreeNode) parent.getLastPathComponent();
		String path = tree.getPathName(parent);
		node.setChecked(handler.checkPathExist(path));
		node.setUpdate(false);
		if(node.getChildCount() > 0 ){
			for (Enumeration<CheckBoxFileTreeNode> children = node.children();
						children.hasMoreElements();) {
				CheckBoxFileTreeNode child = children.nextElement();
				TreePath treePath = parent.pathByAddingChild(child);
				loadData2Tree(treePath);
			}
		}
	}

	private void loadData2Tree(TreePath parent, String paths){
		CheckBoxFileTreeNode node = (CheckBoxFileTreeNode) parent.getLastPathComponent();
		String path = tree.getPathName(parent);
		node.setUpdate(paths.contains(path));

		if(node.getChildCount() > 0 ){
			for (Enumeration<CheckBoxFileTreeNode> children = node.children();
						children.hasMoreElements();) {
				CheckBoxFileTreeNode child = children.nextElement();
				TreePath treePath = parent.pathByAddingChild(child);
				loadData2Tree(treePath, paths);
			}
		}
	}

	private void write2Cache(TreePath parent){
		CheckBoxFileTreeNode node = (CheckBoxFileTreeNode) parent.getLastPathComponent();
		String path = tree.getPathName(parent);
		if(node.isChecked())
			handler.getCache().getPaths().add(path);
		if(node.getChildCount() > 0 ){
			for (Enumeration<CheckBoxFileTreeNode> children = node.children();
						children.hasMoreElements();) {
				CheckBoxFileTreeNode child = children.nextElement();
				TreePath treePath = parent.pathByAddingChild(child);
				write2Cache(treePath);
			}
		}
	}

	protected void checkFileTree() throws Exception{
		if(tree == null){
			JOptionPane.showMessageDialog(this, "Please Load File Tree");
			throw new Exception();
		}
	}

	protected void actionSave(){
		try {
			checkFileTree();
			String newFileName = txtConfigPath.getText();
			handleConfigData(newFileName);
			handler.saveConfig(newFileName);
			loadConfig2UI();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void handleConfigData(String fileName){
		CacheInfo cache = handler.getCache();
		cache.setConfigPath(fileName);
		cache.setComparePath(txtComparePath.getText());
		cache.setCustomPath(txtCustomPath.getText());
		cache.setTargetPath(txtTargetPath.getText());
		cache.setJarPath(txtJarPath.getText());
		cache.setIgnoreFolders(taIgnoreFolders.getText());
		CheckBoxFileTreeNode rootNode = tree.getRootNode();
		cache.getPaths().clear();
		write2Cache(new TreePath(rootNode));
	}

	protected void actionSaveTo(){
		try{
			checkFileTree();
			JFileChooser chooser = new JFileChooser();
			chooser.setFileFilter(new FileFilter() {

				@Override
				public String getDescription() {
					String strFileDesc = "Config File(*.cfg)";
					return strFileDesc;
				}

				@Override
				public boolean accept(File file) {
					String strFileExt = ".cfg";
					if(file.isDirectory() || file.getName().endsWith(strFileExt))
						return true;
					else
						return false;
				}
			});
			chooser.setAcceptAllFileFilterUsed(false);
			chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
			chooser.setDialogTitle("选择保存文件名");
			chooser.setCurrentDirectory(new File(CONFIG_PATH));
			int ok = chooser.showSaveDialog(this);
			if (ok == 0) {
				File cfgFile = chooser.getSelectedFile();
				String fileName = cfgFile.getAbsolutePath();
				String newFileName = fileName + (fileName.endsWith(".cfg")?"":".cfg");

				if (!cfgFile.exists()) {
					new File(newFileName).createNewFile();
				}
				String oldCfgFile = handler.getCache().getConfigPath();
				handler.releaseCfgFile(oldCfgFile);
				handler.lockCfgFile(newFileName);
				handleConfigData(newFileName);
				handler.saveConfig(newFileName);
				loadConfig2UI();
			}
		}catch (Exception e) {
		}
	}

	protected void actionSwitchTree(){
		JFileChooser chooser = new JFileChooser();
		chooser.setAcceptAllFileFilterUsed(false);
		chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		chooser.setDialogTitle("请选择路径");
		if(getSourcePath() != null)
			chooser.setCurrentDirectory(new File(getSourcePath()));
		int ok = chooser.showDialog(this, "确定");
		if (ok == 0) {
			File dir = chooser.getSelectedFile();
			setSourcePath(dir.getAbsolutePath());
			loadTree();
		}
	}

	protected void actionBatchJar(){
		BatchJarUI dialog = new BatchJarUI(this, true, CONFIG_PATH);
		dialog.show();
	}
	
	protected void actionLicence(){
		LicenceUI dialog = new LicenceUI(this, true);
		dialog.show();
	}
	
	protected void actionTrack(){
		TrackerUI dialog = new TrackerUI(this, true);
		dialog.show();
	}

	protected void actionFtp(){
		FtpDialogUI dialog = new FtpDialogUI(this, true, DESTJAT_PATH);
		dialog.show();
	}

	private void loadTree(){
		String sourcePath = getSourcePath();
		tree = new CheckBoxFileTree(new File(sourcePath), false);
		scrollPane.setViewportView(tree);
		contTreePath.setText(sourcePath);
	}

	protected void actionQuit(){
		this.dispose();
	}

	protected void actionExpand(){
		tree.expandAll(new TreePath(tree.getRootNode()),true);
		tree.repaint();
	}

	protected void actionCollapse(){
		tree.collapseRow(0);
		tree.repaint();
	}

	public void setSourcePath(String sourcePath) {
		handler.getCache().setSourcePath(sourcePath);
	}

	public String getSourcePath(){
		return handler.getCache().getSourcePath();
	}


	public static void main(String[] args) {
		new JarToolUI();
	}

}
